package com.aizuda.boot.modules.business.negotiation.service.impl;

import com.aizuda.boot.modules.business.negotiation.entity.ContractNegotiationInstanceEntity;
import com.aizuda.boot.modules.business.negotiation.entity.ContractNegotiationNodeInstanceEntity;
import com.aizuda.boot.modules.business.negotiation.entity.ContractNegotiationParticipantEntity;
import com.aizuda.boot.modules.business.negotiation.mapper.ContractNegotiationInstanceMapper;
import com.aizuda.boot.modules.business.negotiation.mapper.ContractNegotiationNodeInstanceMapper;
import com.aizuda.boot.modules.business.negotiation.mapper.ContractNegotiationParticipantMapper;
import com.aizuda.boot.modules.business.negotiation.service.ContractNegotiationTaskService;
import com.aizuda.bpm.engine.FlowLongEngine;
import com.aizuda.bpm.engine.core.FlowCreator;
import com.aizuda.bpm.engine.core.enums.ProcessType;
import com.aizuda.bpm.engine.entity.FlwProcess;
import com.aizuda.bpm.engine.entity.FlwTask;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 合同协商任务服务实现类
 */
@Slf4j
@Service
public class ContractNegotiationTaskServiceImpl implements ContractNegotiationTaskService {
    
    @Autowired
    private FlowLongEngine flowLongEngine;
    
    @Autowired
    private ContractNegotiationInstanceMapper contractNegotiationInstanceMapper;
    
    @Autowired
    private ContractNegotiationNodeInstanceMapper contractNegotiationNodeInstanceMapper;
    
    @Autowired
    private ContractNegotiationParticipantMapper contractNegotiationParticipantMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handleNegotiationTaskClaim(Long taskId, FlowCreator flowCreator) {
        try {
            log.info("开始处理协商任务认领 - taskId: {}, userId: {}", taskId, flowCreator.getCreateId());
            
            // 1. 根据taskId查找instanceId
            FlwTask flwTask = flowLongEngine.queryService().getTask(taskId);
            if (flwTask == null) {
                log.warn("任务不存在 - taskId: {}", taskId);
                return false;
            }
            
            Long instanceId = flwTask.getInstanceId();
            log.info("查到流程实例ID - instanceId: {}", instanceId);
            
            // 2. 根据instanceId查询processId
            // 先尝试从当前实例查询
            var instance = flowLongEngine.queryService().getInstance(instanceId);
            Long processId = null;
            if (instance != null) {
                processId = instance.getProcessId();
            } else {
                // 如果当前实例不存在，从历史实例查询
                var hisInstance = flowLongEngine.queryService().getHistInstance(instanceId);
                if (hisInstance != null) {
                    processId = hisInstance.getProcessId();
                }
            }
            
            if (processId == null) {
                log.warn("无法找到流程定义ID - instanceId: {}", instanceId);
                return false;
            }
            
            log.info("查到流程定义ID - processId: {}", processId);
            
            // 3. 在flw_process表中根据process_id查询process_type
            FlwProcess flwProcess = flowLongEngine.processService().getProcessById(processId);
            if (flwProcess == null) {
                log.warn("流程定义不存在 - processId: {}", processId);
                return false;
            }
            
            String processType = flwProcess.getProcessType();
            log.info("查到流程类型 - processType: {}", processType);
            
            // 4. 如果processType不是business_audit，直接返回true（不需要处理）
            if (!ProcessType.business_audit.eq(processType)) {
                log.info("流程类型不是business_audit，无需处理协商逻辑 - processType: {}", processType);
                return true;
            }
            
            // 5. 根据instanceId查看绑定了哪一个contractId
            Integer contractId = getContractIdByInstanceId(instanceId);
            if (contractId == null) {
                log.warn("无法找到关联的合同ID - instanceId: {}", instanceId);
                return false;
            }
            
            log.info("查到关联的合同ID - contractId: {}", contractId);
            
            // 6. 查出当前task对应的contract_negotiation_node_instance对应的哪一个节点
            Integer nodeInstanceId = findNegotiationNodeInstanceId(taskId, contractId);
            if (nodeInstanceId == null) {
                log.warn("无法找到对应的协商节点实例 - taskId: {}, contractId: {}", taskId, contractId);
                return false;
            }
            
            log.info("查到协商节点实例ID - nodeInstanceId: {}", nodeInstanceId);
            
            // 7. 在contract_negotiation_participant将当前认领任务的用户加入表中
            Long userId = Long.valueOf(flowCreator.getCreateId());
            boolean success = addUserToNegotiationParticipant(contractId, nodeInstanceId, userId);
            
            if (success) {
                log.info("协商任务认领处理成功 - taskId: {}, userId: {}, contractId: {}, nodeInstanceId: {}", 
                        taskId, userId, contractId, nodeInstanceId);
            } else {
                log.warn("协商任务认领处理失败 - taskId: {}, userId: {}", taskId, userId);
            }
            
            return success;
            
        } catch (Exception e) {
            log.error("处理协商任务认领异常 - taskId: {}, userId: {}", taskId, flowCreator.getCreateId(), e);
            throw e;
        }
    }
    
    @Override
    public Integer getContractIdByInstanceId(Long instanceId) {
        try {
            // 根据流程实例ID查询协商实例
            List<ContractNegotiationInstanceEntity> instances = contractNegotiationInstanceMapper.selectList(
                    new LambdaQueryWrapper<ContractNegotiationInstanceEntity>()
                            .eq(ContractNegotiationInstanceEntity::getProcessInstanceId, instanceId)
                            .orderByDesc(ContractNegotiationInstanceEntity::getCreatedAt)
            );
            
            if (!instances.isEmpty()) {
                return instances.get(0).getContractId();
            }
            
            log.warn("未找到对应的协商实例 - instanceId: {}", instanceId);
            return null;
            
        } catch (Exception e) {
            log.error("查询合同ID异常 - instanceId: {}", instanceId, e);
            return null;
        }
    }
    
    @Override
    public Integer findNegotiationNodeInstanceId(Long taskId, Integer contractId) {
        try {
            // 先获取任务信息，主要是为了获取taskKey
            FlwTask flwTask = flowLongEngine.queryService().getTask(taskId);
            if (flwTask == null) {
                return null;
            }
            
            // 查询该合同的协商实例
            ContractNegotiationInstanceEntity negotiationInstance = contractNegotiationInstanceMapper.selectOne(
                    new LambdaQueryWrapper<ContractNegotiationInstanceEntity>()
                            .eq(ContractNegotiationInstanceEntity::getContractId, contractId)
                            .eq(ContractNegotiationInstanceEntity::getProcessInstanceId, flwTask.getInstanceId())
                            .orderByDesc(ContractNegotiationInstanceEntity::getCreatedAt)
                            .last("LIMIT 1")
            );
            
            if (negotiationInstance == null) {
                log.warn("未找到协商实例 - contractId: {}, instanceId: {}", contractId, flwTask.getInstanceId());
                return null;
            }
            
            // 查询当前节点（isCurrentNode = true）或者通过taskId匹配
            ContractNegotiationNodeInstanceEntity nodeInstance = contractNegotiationNodeInstanceMapper.selectOne(
                    new LambdaQueryWrapper<ContractNegotiationNodeInstanceEntity>()
                            .eq(ContractNegotiationNodeInstanceEntity::getInstanceId, negotiationInstance.getId())
                            .and(wrapper -> wrapper
                                    .eq(ContractNegotiationNodeInstanceEntity::getIsCurrentNode, true)
                                    .or()
                                    .eq(ContractNegotiationNodeInstanceEntity::getTaskId, taskId)
                            )
                            .orderByAsc(ContractNegotiationNodeInstanceEntity::getSortOrder)
                            .last("LIMIT 1")
            );
            
            if (nodeInstance != null) {
                // 更新该节点的taskId（如果还没有设置的话）
                if (nodeInstance.getTaskId() == null) {
                    nodeInstance.setTaskId(taskId);
                    nodeInstance.setUpdatedAt(LocalDateTime.now());
                    contractNegotiationNodeInstanceMapper.updateById(nodeInstance);
                    log.info("更新协商节点实例的taskId - nodeInstanceId: {}, taskId: {}", nodeInstance.getId(), taskId);
                }
                
                return nodeInstance.getId();
            }
            
            log.warn("未找到匹配的协商节点实例 - contractId: {}, taskId: {}", contractId, taskId);
            return null;
            
        } catch (Exception e) {
            log.error("查询协商节点实例异常 - taskId: {}, contractId: {}", taskId, contractId, e);
            return null;
        }
    }
    
    @Override
    public boolean addUserToNegotiationParticipant(Integer contractId, Integer nodeInstanceId, Long userId) {
        try {
            // 查询协商实例ID
            ContractNegotiationInstanceEntity negotiationInstance = contractNegotiationInstanceMapper.selectOne(
                    new LambdaQueryWrapper<ContractNegotiationInstanceEntity>()
                            .eq(ContractNegotiationInstanceEntity::getContractId, contractId)
                            .orderByDesc(ContractNegotiationInstanceEntity::getCreatedAt)
                            .last("LIMIT 1")
            );
            
            if (negotiationInstance == null) {
                log.warn("未找到协商实例 - contractId: {}", contractId);
                return false;
            }
            
            // 检查用户是否已经是该节点的参与者
            ContractNegotiationParticipantEntity existingParticipant = contractNegotiationParticipantMapper.selectOne(
                    new LambdaQueryWrapper<ContractNegotiationParticipantEntity>()
                            .eq(ContractNegotiationParticipantEntity::getInstanceId, negotiationInstance.getId())
                            .eq(ContractNegotiationParticipantEntity::getNodeInstanceId, nodeInstanceId)
                            .eq(ContractNegotiationParticipantEntity::getEmployeeId, userId)
            );
            
            if (existingParticipant != null) {
                log.info("用户已经是该节点的参与者 - userId: {}, nodeInstanceId: {}", userId, nodeInstanceId);
                return true;
            }
            
            // 创建新的参与者记录
            ContractNegotiationParticipantEntity participant = new ContractNegotiationParticipantEntity()
                    .setInstanceId(negotiationInstance.getId())
                    .setNodeInstanceId(nodeInstanceId)
                    .setEmployeeId(userId)
                    .setParticipantType("NODE_PARTICIPANT")
                    .setIsViewed(false)
                    .setIsConfirmed(false)
                    .setCreatedAt(LocalDateTime.now())
                    .setUpdatedAt(LocalDateTime.now());
            
            int result = contractNegotiationParticipantMapper.insert(participant);
            
            if (result > 0) {
                log.info("成功添加协商参与者 - userId: {}, nodeInstanceId: {}, participantId: {}", 
                        userId, nodeInstanceId, participant.getId());
                return true;
            } else {
                log.warn("添加协商参与者失败 - userId: {}, nodeInstanceId: {}", userId, nodeInstanceId);
                return false;
            }
            
        } catch (Exception e) {
            log.error("添加协商参与者异常 - contractId: {}, nodeInstanceId: {}, userId: {}", 
                    contractId, nodeInstanceId, userId, e);
            return false;
        }
    }
} 